#ifndef REPORT_H
#define REPORT_H

/*****************************************************************************/
/* Real */
typedef struct Report_Real_t
{
  long cnt;                                  /* number of updates */
  long null_cnt;                             /* number of Null updates */

  double sum;
  double sum_of_sq;

  double last_val;
  int last_is_null;
} Report_Real_t;

void Report_Real_Init(Report_Real_t * stat);
void Report_Real_Update(Report_Real_t * stat, double val);
void Report_Real_Update_Null(Report_Real_t * stat);
void Report_Real_Compute(const Report_Real_t * stat, double * pavg,
                         double * psd);
void Report_Real_Print(const Report_Real_t * stat);
void Report_Real_Print_Last(const Report_Real_t * stat);

/*****************************************************************************/
/* NaturalNum */
typedef struct Report_NaturalNum_t
{
  long cnt;                                  /* number of updates */
  long null_cnt;                             /* number of Null updates */

  int  num_val;                              /* size of p_valcnt array */
  long * p_valcnt;                           /* count of each value */

  int last_val;
  int last_is_null;
} Report_NaturalNum_t;

void Report_NaturalNum_Init(Report_NaturalNum_t * stat);
void Report_NaturalNum_Update(Report_NaturalNum_t * stat, int val);
void Report_NaturalNum_Update_Null(Report_NaturalNum_t * stat);
void Report_NaturalNum_Compute(const Report_NaturalNum_t * stat, 
                               int * p_num_val, double ** p_p_valcnt);
void Report_NaturalNum_Print(const Report_NaturalNum_t * stat);
void Report_NaturalNum_Print_Last(const Report_NaturalNum_t * stat);


/*****************************************************************************/
/* Finite types */
typedef struct Report_Finite_t
{
  long cnt;                                  /* number of updates */
  long null_cnt;                             /* number of Null updates */
  
  int num_obj;
  long * obj_cnt;
  char ** obj_names;

  int last_val;
  int last_is_null;
} Report_Finite_t;

/* give the name of all the objects */
void Report_Finite_Init(Report_Finite_t * stat, int num_obj, ...);
void Report_Finite_Update(Report_Finite_t * stat, int val);
void Report_Finite_Update_Null(Report_Finite_t * stat);
/* client must free obj_prob */
void Report_Finite_Compute(const Report_Finite_t * stat, int * num_obj,
                           double ** obj_prob);
void Report_Finite_Print(const Report_Finite_t * stat);
void Report_Finite_Print_Last(const Report_Finite_t * stat);


#endif /* REPORT_H */
